#include "seti_bs.h"
#include "display.h"
#include "file.h"

LRESULT CALLBACK AboutProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
	switch(iMsg) {
		case WM_INITDIALOG:	
			sprintf(szMessage,"%s %s\r\n",PROG_TITLE,PROG_VER);
			strcat(szMessage,"For SETI Brainstorm\r\n\r\n");
			strcat(szMessage,"Wesley Hopper (hopperw2000@yahoo.com)\r\n");
			SetDlgItemText(hWnd,IDC_ABOUT,szMessage);
			return 0;

		case WM_LBUTTONDOWN: 
		case WM_CLOSE: 
			EndDialog(hWnd,0); 
			return 0;
	}

	return 0;
}

int GetEditValue(int iDlgItem, int &iValue, int iMin, int iMax) {
	int iEditValue=GetDlgItemInt(hMainDlg,iDlgItem,false,false);
	int iNewValue=iEditValue;
	iNewValue=MAX(iNewValue,iMin); //bound to lower limit
	iNewValue=MIN(iNewValue,iMax); //bound to upper limit

	if(iNewValue!=iEditValue) SetDlgItemInt(hMainDlg,iDlgItem,iNewValue,FALSE); //set edit if bounded
	
	if(iNewValue==iValue) return 0;
	
	iValue=iNewValue;
	return 1;
}

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
	PAINTSTRUCT psPaint;
	SCROLLINFO siScroll;
	int iSetValue;
	unsigned int iLineSkip, iPageSkip;
	unsigned long ulOldTimeStart;
	
	switch(iMsg)
	{
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				case IDM_FILE_OPEN:
					if(!GetOFN(szFileName,szOpenFileFilter)) return 0;
					CreateThread(NULL,128,LoadFile,NULL,0,NULL);
					return 0;

				case IDM_FILE_EXP_TEXT:
					if(!rrRawFile.iBlocks) return 0;
					CreateThread(NULL,128,ExportFile,NULL,0,NULL);
					Sleep(50);
					DialogBox(hInst,MAKEINTRESOURCE(IDD_PROGRESS),hMainDlg,(DLGPROC)ProgressProc);
					return 0;

				case IDM_FILE_EXIT:
					rrRawFile.Close();
					SendMessage(hMainDlg,WM_CLOSE,0,0);
					return 0;

				case IDM_HELP_ABOUT:
					DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUT),hMainDlg,(DLGPROC)AboutProc);
					return 0;

				case IDC_BLOCK_EDIT: {
					if(HIWORD(wParam)!=EN_CHANGE) return 0;
					if(!rrRawFile.iBlocks) return 0;

					if(!GetEditValue(IDC_BLOCK_EDIT,iSetValue,1,rrRawFile.iBlocks)) return 0;
					int iError=rrRawFile.BlockSet(iSetValue-1);
					if(iError) ErrorMessage(hMainDlg,iError);
					iSetValue=rrRawFile.iCurBlock+1;
					SetDlgInfo();
					return 0;
				}

				case IDC_HEIGHT_EDIT: {
					if(HIWORD(wParam)!=EN_CHANGE) return 0;
					if(!rrRawFile.iBlocks) return 0;

					if(!GetEditValue(IDC_HEIGHT_EDIT,iTimeHeight,1,8)) return 0;
					SetPlotInfo();
					return 0;
				}

				case IDC_ZOOM_EDIT: {
					if(HIWORD(wParam)!=EN_CHANGE) return 0;
					if(!rrRawFile.iBlocks) return 0;

					if(!GetEditValue(IDC_ZOOM_EDIT,iTimeZoom,1,iMaxZoom)) return 0;
					SetPlotInfo();
					return 0;
				}

				case IDC_ZOOM_MAX:
					iTimeZoom=iMaxZoom;
					SetDlgItemInt(hMainDlg,IDC_ZOOM_EDIT,iTimeZoom,false);
					SetPlotInfo();
					return 0;				   

				/*case IDC_PLAY: 
					if(audioPlaying()) audioPause();
					else {
						audioPlay();
						CreateThread(NULL,128,PlayAudio,NULL,0,NULL);
					}
					return 0;*/

				case IDCANCEL:
					//DestroyWindow(hMainDlg);
					EndDialog(hMainDlg,0);
					PostQuitMessage(0);
					return 0;

				default: return 0;
			}

		case WM_VSCROLL: { //scrollbar movement
			if(!rrRawFile.iBlocks) return 0;

			ulOldTimeStart=ulTimeStart;

			iLineSkip=16*iTimeZoom; //line height
			iPageSkip=iPlotHeight*iTimeZoom; //page height

			switch(LOWORD(wParam)) {
				case SB_PAGEUP:		ulTimeStart=(ulTimeStart<iPageSkip? 0:ulTimeStart-iPageSkip);	break;
				case SB_LINEUP:		ulTimeStart=(ulTimeStart<iLineSkip? 0:ulTimeStart-iLineSkip);	break;
				case SB_PAGEDOWN:	ulTimeStart+=iPageSkip;		break;
				case SB_LINEDOWN:	ulTimeStart+=iLineSkip;		break;
				case SB_BOTTOM:		ulTimeStart=ulMaxTimeStart;	break;
				case SB_TOP:		ulTimeStart=0;				break;
				case SB_THUMBTRACK:	
					ZeroMemory(&siScroll,sizeof(SCROLLINFO));
					siScroll.cbSize=sizeof(SCROLLINFO);
					siScroll.fMask=SIF_TRACKPOS; 
					if(GetScrollInfo(hTimeScroll,SB_CTL,&siScroll))
						ulTimeStart=siScroll.nTrackPos;	
					break;
			}
			
			if(ulTimeStart>ulMaxTimeStart) ulTimeStart=ulMaxTimeStart;

			if(ulTimeStart!=ulOldTimeStart) { //only update if moved
				SetScrollPos(hTimeScroll,SB_CTL,ulTimeStart,TRUE);
				SetTimeOffset();
				RenderPlot();
			}
			return 0;
		}

		case WM_LBUTTONDOWN: { //get sample info
			if(!rrRawFile.iBlocks) return 0;

			//get click coordinates
			pClick.x=pDrag.x=LOWORD(lParam);
			pClick.y=pDrag.y=HIWORD(lParam);
			SetSelByPoints();
			SetSelSample();			
			return 0;
		}

		case WM_RBUTTONDOWN: {
			if(!rrRawFile.iBlocks) return 0;

			
			
			//rrRawFile.rbBlock.GetFFT(iSelChan,ulSelTime,ulSelRange,vFreq);
			//rrRawFile.rbBlock.GetFFT(iSelChan,0,rrRawFile.rbBlock.ulObsTimes,vFreq);
			return 0;
		}

		case WM_LBUTTONDBLCLK:
			ulSelTime=0;
			ulSelRange=rrRawFile.rbBlock.ulObsTimes;
			SetSelSample();
			return 0;

		case WM_MOUSEMOVE: {
			if(!rrRawFile.iBlocks) return 0;

			if(wParam==MK_LBUTTON) {
				//get drag coordinates
				pDrag.x=LOWORD(lParam);
				pDrag.y=HIWORD(lParam);
				SetSelByPoints();
				SetSelSample();	
			}
			return 0;
		}

		case WM_PAINT: //reblit plot
			BeginPaint(hMainDlg,&psPaint);
			DrawPlot();			
			EndPaint(hMainDlg,&psPaint);
			return 0;
			
		case WM_CLOSE:
			PostMessage(hMainDlg,WM_DESTROY,0,0);
			return 0;

		case WM_DESTROY: 
			PostQuitMessage(0); 
			return 0;
	}

	//return DefWindowProc(hWnd,iMsg,wParam,lParam);
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
	hInst=hInstance;
	MSG Msg;

	//create dialog window
	hMainDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_MAINDLG),NULL,(DLGPROC)MainWndProc);
	SendMessage(hMainDlg,WM_SETICON,ICON_BIG,(WPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAIN)));
	SetWindowText(hMainDlg,PROG_TITLE);
	ShowWindow(hMainDlg,SW_SHOWNORMAL);
	hProgDlg=NULL;

	//make pens
	hpBlackPen=CreatePen(PS_SOLID,2,RGB(0,0,0));
	hpNullPen=(HPEN)GetStockObject(NULL_PEN);
	hpGreenPen=CreatePen(PS_SOLID,1,RGB(0,255,0));
	
	//make brushes
	hbWhiteBrush=(HBRUSH)GetStockObject(WHITE_BRUSH); 
	hbBlackBrush=(HBRUSH)GetStockObject(BLACK_BRUSH);
	hbNullBrush=(HBRUSH)GetStockObject(NULL_BRUSH);

	//setup window device
	hdcWnd=GetDC(hMainDlg);
	SelectObject(hdcWnd,hpBlackPen);
	SelectObject(hdcWnd,hbNullBrush);
	
	//create plot font
	hfPlotFont=CreateFont(iCharHeight,iCharWidth,0,0,FW_NORMAL,0,0,0,0,0,0,0,0,"SETIfont");
	SelectObject(hdcWnd,hfPlotFont);

	//create drawing device context 
	hdcMem=CreateCompatibleDC(hdcWnd);
	SelectObject(hdcMem,hpNullPen);	

	//create bitmap for drawing DC
	hBmp=CreateCompatibleBitmap(hdcWnd,iPlotWidth,iPlotHeight);
	SelectObject(hdcMem,hBmp); 

	hMainMenu=GetMenu(hMainDlg); //menu handle
	EnableMenu(MF_GRAYED);

	HACCEL hAcc=LoadAccelerators(hInst,MAKEINTRESOURCE(IDR_ACCELERATORS));
	hTimeScroll=GetDlgItem(hMainDlg,IDC_TIME_SCROLL); //scroll bar handle

	//get full window, client, and scroll bar rectangles
	//GetClientRect(hMainDlg,&rClientRect);
	GetWindowRect(GetDlgItem(hMainDlg,IDC_TIME_SCROLL),&rScroll);

	//get client top/left relative to full window
	POINT pOrigin; pOrigin.x=0; pOrigin.y=0;
	ClientToScreen(hMainDlg,&pOrigin);

	//set plot rectangle
	rPlot.top=rScroll.top-pOrigin.y+2;
	rPlot.left=rScroll.left-iPlotWidth-pOrigin.x-2;
	rPlot.right=rPlot.left+iPlotWidth;
	rPlot.bottom=rPlot.top+iPlotHeight;

	//init audio
	//if(!audioStartup(hMainDlg,iSamplesPerSecond,iBitsPerSample))
	//	MessageBox(hMainDlg,"Could not open wave mapper","Error",MB_OK | MB_ICONERROR);

	//audioSetVolume(10000);

	while(GetMessage(&Msg,NULL,0,0)) {
		if(!TranslateAccelerator(hMainDlg, hAcc, &Msg))
			if(!IsDialogMessage(hMainDlg,&Msg)) {	
				TranslateMessage(&Msg);
				DispatchMessage(&Msg);
			}
	}

	//audioShutdown();

	return(Msg.wParam);
}
